Maybe even the same thing with the superior colliculus and eye movements (although that's less clear)
So what should this representation be?
In [6]:
    
import numpy
def gabor(width, height, lambd, theta, psi, sigma, gamma, x_offset, y_offset):
    x = numpy.linspace(-1, 1, width)
    y = numpy.linspace(-1, 1, height)
    X, Y = numpy.meshgrid(x, y)
    X = X - x_offset
    Y = Y + y_offset
    cosTheta = numpy.cos(theta)
    sinTheta = numpy.sin(theta)
    xTheta = X * cosTheta  + Y * sinTheta
    yTheta = -X * sinTheta + Y * cosTheta
    e = numpy.exp( -(xTheta**2 + yTheta**2 * gamma**2) / (2 * sigma**2) )
    cos = numpy.cos(2 * numpy.pi * xTheta / lambd + psi)
    return e * cos
g = gabor(500, 500, lambd=0.6, 
                    theta=numpy.pi/4, 
                    psi=numpy.pi/2, 
                    sigma=0.2, 
                    gamma=0.7,
                    x_offset=0,
                    y_offset=0)
import pylab
pylab.imshow(g, extent=(-1, 1, -1, 1), interpolation='none', vmin=-1, vmax=1, cmap='gray')
pylab.show()
    
    
In [7]:
    
width = 50
height = 50
N = 100
def make_random_gabor(width, height):
    return gabor(width, height, 
                  lambd=random.uniform(0.3, 0.8),
                  theta=random.uniform(0, 2*numpy.pi),
                  psi=random.uniform(0, 2*numpy.pi),
                  sigma=random.uniform(0.2, 0.5),
                  gamma=random.uniform(0.4, 0.8),
                  x_offset=random.uniform(-1, 1),
                  y_offset=random.uniform(-1, 1))
encoders = [make_random_gabor(width, height) for i in range(N)]
import pylab
pylab.figure(figsize=(10,8))
for i in range(N):
    w = i%12
    h = i/12
    pylab.imshow(encoders[i], extent=(w, w+0.95, h, h+0.95), interpolation='none',
                 vmin=-1, vmax=1, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, N/12))
    
pylab.show()
    
    
In [8]:
    
S = 100
width = 50
height = 50
x = numpy.random.normal(size=(width*height, S))
import pylab
pylab.figure(figsize=(10,8))
for i in range(S):
    w = i%12
    h = i/12
    img = x[:,i]
    img.shape = width, height
    pylab.imshow(img, extent=(w, w+0.95, h, h+0.95), interpolation='none',
                 vmin=-1, vmax=1, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, S/12))
    
pylab.show()
    
    
In [9]:
    
S = 100
width = 50
height = 50
def normalize(v):
    return v/numpy.linalg.norm(v)
C = 4
x = [normalize(numpy.sum([make_random_gabor(width, height) for i in range(C)],axis=0).flatten()) for j in range(S)]
x = numpy.array(x).T
import pylab
pylab.figure(figsize=(10,8))
for i in range(S):
    w = i%12
    h = i/12
    img = x[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(w, w+0.95, h, h+0.95), interpolation='none',
                 vmin=-0.1, vmax=0.1, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, S/12))
    
pylab.show()
    
    
In [10]:
    
import syde556
S = 100
x = []
for i in range(S):
    sx, A = syde556.generate_signal(T=width, dt=1.0, rms=1, limit=0.05, seed=i)
    sy, A = syde556.generate_signal(T=height, dt=1.0, rms=1, limit=0.05, seed=i+2000)
    SX, SY = numpy.meshgrid(sx, sy)
    img = SX*SY
    x.append(normalize(img.flatten()))
x = numpy.array(x).T
import pylab
pylab.figure(figsize=(10,8))
for i in range(S):
    w = i%12
    h = i/12
    img = x[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(w, w+0.95, h, h+0.95), interpolation='none',
                 vmin=-0.1, vmax=0.1, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, S/12))
    
pylab.show()
    
    
In [11]:
    
import syde556
reload(syde556)
N = 100
width = 50
height = 50
encoders = [make_random_gabor(width, height).flatten() for i in range(N)]
vision = syde556.Ensemble(neurons=N, dimensions=width*height, encoders=encoders)
decoder = vision.compute_decoder(x, x, noise=0.1)
A, xhat = vision.simulate_rate(x, decoder)
    
In [12]:
    
import pylab
pylab.figure(figsize=(10,12))
for i in range(S):
    w = i%6
    h = i/6
    img = x[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(2*w, 2*w+0.9, h, h+0.9), interpolation='none',
                 vmin=-0.1, vmax=0.1, cmap='gray')
    img = xhat[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(2*w+0.95, 2*w+1.85, h, h+0.9), interpolation='none',
                 vmin=-0.1, vmax=0.1, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, S/6))
    
pylab.show()
    
    
In [17]:
    
width = 50
height = 50
# make samples
S = 100
x = []
for i in range(S):
    sx, A = syde556.generate_signal(T=width, dt=1.0, rms=1, limit=2.5/width, seed=i)
    sy, A = syde556.generate_signal(T=height, dt=1.0, rms=1, limit=2.5/height, seed=i+2000)
    SX, SY = numpy.meshgrid(sx, sy)
    img = SX*SY
    x.append(normalize(img.flatten()))
x = numpy.array(x).T
print x.shape
#make neurons
N = 500
encoders = [make_random_gabor(width, height).flatten() for i in range(N)]
vision = syde556.Ensemble(neurons=N, dimensions=width*height, encoders=encoders)
decoder = vision.compute_decoder(x, x, noise=0.1)
A, xhat = vision.simulate_rate(x, decoder)
scale = 5/np.sqrt(width*height)
#plot results
import pylab
pylab.figure(figsize=(10,12))
for i in range(S):
    w = i%6
    h = i/6
    img = x[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(2*w, 2*w+0.9, h, h+0.9), interpolation='none',
                 vmin=-scale, vmax=scale, cmap='gray')
    img = xhat[:,i]
    img.shape = height, width
    pylab.imshow(img, extent=(2*w+0.95, 2*w+1.85, h, h+0.9), interpolation='none',
                 vmin=-scale, vmax=scale, cmap='gray')
    pylab.xticks([])
    pylab.yticks([])
pylab.xlim((0, 12))
pylab.ylim((0, S/6))
    
pylab.show()
    
    
    
Still have to be able to compute $\int x(v) e(v) dv$
$\int x(v) e(v) dv$
Let's assume $b_i(v)$ are orthogonal
$\int (\sum_i c_{x,i} c_{e,i} b_i(v)^2)dv$
In [134]:
    
import numpy
v = numpy.linspace(-1, 1, 1000)
b_i = v**1
b_j = v**2
import pylab
pylab.plot(v, b_i, label='$b_i$')
pylab.plot(v, b_j, label='$b_j$')
pylab.plot(v, b_i*b_j, label='$b_i b_j$')
pylab.legend(loc='best')
xlabel('$v$')
pylab.show()
dv = 2.0/len(v)
print 'sum:', numpy.sum(b_i*b_j*dv)
    
    
    
In [135]:
    
for i in range(5):
    plot(v, numpy.polynomial.legendre.legval(v, numpy.eye(5)[i]))
xlabel('$v$')
show()
    
    
In [136]:
    
import numpy
v = numpy.linspace(-1, 1, 1000)
i = 1
j = 2
b_i = numpy.polynomial.legendre.legval(v, numpy.eye(i+1)[i])
b_j = numpy.polynomial.legendre.legval(v, numpy.eye(j+1)[j])
import pylab
pylab.plot(v, b_i, label='$b_i$', linewidth=3)
pylab.plot(v, b_j, label='$b_j$', linewidth=3)
pylab.plot(v, b_i*b_j, label='$b_i b_j$')
pylab.legend(loc='best')
xlabel('$v$')
pylab.show()
dv = 2.0/len(v)
print 'sum:', numpy.sum(b_i*b_j*dv)
    
    
    
In [137]:
    
v = numpy.linspace(-1, 1, 1000)
dv = 2.0/len(v)
length = []
for i in range(10):
    b_i = numpy.polynomial.legendre.legval(v, numpy.eye(i+1)[i])
    length.append(sum(b_i*b_i)*dv)
plot(length)  
xlabel('$i$')
show()
    
    
In [138]:
    
v = numpy.linspace(-1, 1, 1000)
dv = 2.0/len(v)
length = []
for i in range(10):
    b_i = numpy.polynomial.legendre.legval(v, numpy.eye(i+1)[i])
    b_i = b_i * numpy.sqrt((2*i + 1)/2.0)
    length.append(sum(b_i*b_i)*dv)
plot(length)  
xlabel('$i$')
ylim(0, 2)
show()
    
    
In [294]:
    
for i in range(5):
    plot(v, numpy.polynomial.legendre.legval(v, numpy.eye(i+1)[i])* numpy.sqrt((2*i + 1)/2.0))
xlabel('$v$')    
show()
    
    
In [295]:
    
D = 5
S = 20
x_poly = numpy.random.randn(D, S)/numpy.sqrt(D)
v = numpy.linspace(-1, 1, 1000)
for i in range(S):
    plot(v, numpy.polynomial.polynomial.polyval(v, x_poly[:,i]))
xlabel('$v$')    
show()
    
    
In [296]:
    
x = []
for i in range(S):
    x.append(numpy.polynomial.legendre.poly2leg(x_poly[:,i])/numpy.sqrt((2*i + 1)/2.0))
x = numpy.array(x).T
v = numpy.linspace(-1, 1, 1000)
for i in range(S):
    plot(v, numpy.polynomial.legendre.legval(v, x[:,i])*numpy.sqrt((2*i + 1)/2.0))
xlabel('$v$')
show()
    
    
In [297]:
    
N = 50
ensemble = syde556.Ensemble(neurons=N, dimensions=5)
decoder = ensemble.compute_decoder(x, x, noise=0.1)
A, xhat = ensemble.simulate_rate(x, decoder)
figure(figsize=(10,4))
subplot(1, 2, 1)
for i in range(S):
    plot(v, numpy.polynomial.legendre.legval(v, x[:,i])*numpy.sqrt((2*i + 1)/2.0))
ylim(-3, 3)
xlabel('$v$')
title('original')
subplot(1, 2, 2)
for i in range(S):
    plot(v, numpy.polynomial.legendre.legval(v, xhat[:,i])*numpy.sqrt((2*i + 1)/2.0))
ylim(-3, 3)
xlabel('$v$')
title('decoded')
show()
    
    
In [298]:
    
def area(x):
    fv = numpy.polynomial.legendre.legval(v, x)*numpy.sqrt((2*i + 1)/2.0)
    a = sum(fv)*dv
    return [a]
fx = numpy.array([area(xx) for xx in x.T]).T
    
decoder = ensemble.compute_decoder(x, fx, noise=0.1)
A, fxhat = ensemble.simulate_rate(x, decoder)
for i in range(10):
    print x[:,i], fx[:,i], fxhat[:,i]
    
    
In [300]:
    
def maximum(x):
    fv = numpy.polynomial.legendre.legval(v, x)*numpy.sqrt((2*i + 1)/2.0)
    index = numpy.argmax(fv)
    return [v[index]]
fx = numpy.array([maximum(xx) for xx in x.T]).T
    
decoder = ensemble.compute_decoder(x, fx, noise=0.01)
A, fxhat = ensemble.simulate_rate(x, decoder)
for i in range(20):
    print x[:,i], fx[:,i], fxhat[:,i]
    
    
In [301]:
    
def negative(x):
    return -x
fx = numpy.array([negative(xx) for xx in x.T]).T
    
decoder = ensemble.compute_decoder(x, fx, noise=0.01)
A, fxhat = ensemble.simulate_rate(x, decoder)
figure(figsize=(10,4))
subplot(1, 2, 1)
for i in range(S):
    plot(v, numpy.polynomial.legendre.legval(v, x[:,i])*numpy.sqrt((2*i + 1)/2.0))
xlabel('$v$')
ylim(-3, 3)
title('original')
subplot(1, 2, 2)
for i in range(S):
    plot(v, numpy.polynomial.legendre.legval(v, fxhat[:,i])*numpy.sqrt((2*i + 1)/2.0))
xlabel('$v$')
ylim(-3, 3)
title('decoded')
show()
    
    
In [187]:
    
N = 200
v = numpy.linspace(-1, 1, 1000)
def make_gaussian(centre, sigma):
    return numpy.exp(-(v-centre)**2/(2*sigma**2))
encoders = numpy.array([make_gaussian(centre=random.uniform(-1, 1), 
                          sigma=0.1) for i in range(N)])
plot(v, encoders[:20].T)
xlabel('$v$')
show()
    
    
In [192]:
    
U, S, V = numpy.linalg.svd(encoders.T)
plot(v, U[:,:10])
xlabel('$v$')
show()
    
    
In [198]:
    
import numpy
v = numpy.linspace(-1, 1, 1000)
i = 0
j = 1
b_i = U[:,i]
b_j = U[:,j]
import pylab
pylab.plot(v, b_i, label='$b_i$', linewidth=3)
pylab.plot(v, b_j, label='$b_j$', linewidth=3)
pylab.plot(v, b_i*b_j, label='$b_i b_j$')
pylab.legend(loc='best')
xlabel('$v$')
pylab.show()
dv = 2.0/len(v)
print 'sum:', numpy.sum(b_i*b_j*dv)
    
    
    
In [209]:
    
v = numpy.linspace(-1, 1, 1000)
dv = 2.0/len(v)
length = []
for i in range(10):
    b_i = U[:,i]
    length.append(sum(b_i*b_i)*dv)
plot(length)  
xlabel('$i$')
ylim(0, 0.004)
show()
    
    
In [224]:
    
v = numpy.linspace(-1, 1, 1000)
dv = 2.0/len(v)
basis = U/(math.sqrt(dv))
length = []
for i in range(10):
    b_i = basis[:,i]
    length.append(sum(b_i*b_i)*dv)
plot(length)  
xlabel('$i$')
ylim(0, 2)
show()
    
    
In [228]:
    
plot(v, basis[:, :10])
xlabel('$v$')
show()
    
    
In [223]:
    
plot(S)
show()
    
    
In [288]:
    
bases = 20
figure(figsize=(10,4))
subplot(1, 2, 1)
plot(v, encoders.T[:,:20])
ylim(0,1)
title('original')
subplot(1, 2, 2)
basis = U[:,:bases]/(math.sqrt(dv))
e = numpy.dot(encoders, basis)*dv
plot(v, numpy.dot(basis, e.T)[:,:20])
ylim(0,1)
title('bases=%d'%bases)
show()
    
    
In [289]:
    
S = 100
import syde556
x = numpy.array([syde556.generate_signal(2.0, 2.0/1000, 
                  rms=0.5, limit=2, seed=i)[0] for i in range(S)])
plot(v, x[:5].T)
xlabel('$v$')
show()
    
    
In [290]:
    
figure(figsize=(10,4))
subplot(1, 2, 1)
plot(v, x.T[:,:20])
title('original')
subplot(1, 2, 2)
basis = U[:,:bases]/(math.sqrt(dv))
x_vector = numpy.dot(x, basis)*dv
plot(v, numpy.dot(basis, x_vector.T)[:,:20])
title('bases=%d'%bases)
show()
    
    
In [332]:
    
N = 200
bases = 20
S = 200 
encoders = numpy.array([make_gaussian(centre=random.uniform(-1, 1), 
                          sigma=0.1) for i in range(N)])
U, Sing, V = numpy.linalg.svd(encoders.T)
basis = U[:,:bases]/(math.sqrt(dv))
e = numpy.dot(encoders, basis)*dv
x_func = numpy.array([syde556.generate_signal(2.0, 2.0/1000, 
                  rms=0.5, limit=2, seed=i)[0] for i in range(S)])
x = numpy.dot(x_func, basis).T*dv
ensemble = syde556.Ensemble(neurons=N, dimensions=bases, encoders=e)
decoder = ensemble.compute_decoder(x, x, noise=0.1)
A, xhat = ensemble.simulate_rate(x, decoder)
figure(figsize=(10,4))
subplot(1, 2, 1)
plot(v, x_func.T[:,:20])
ylim(-4, 4)
title('original')
subplot(1, 2, 2)
basis = U[:,:bases]/(math.sqrt(dv))
xhat_func = numpy.dot(basis, xhat)
plot(v, xhat_func[:,:20])
title('bases=%d'%bases)
ylim(-4, 4)
show()
    
    
In [347]:
    
N = 200
bases = 20
S = 200 
encoders = numpy.array([make_gaussian(centre=random.uniform(-1, 1), 
                          sigma=0.1) for i in range(N)])
U, Sing, V = numpy.linalg.svd(encoders.T)
basis = U[:,:bases]/(math.sqrt(dv))
e = numpy.dot(encoders, basis)*dv
x_func = numpy.array([syde556.generate_signal(2.0, 2.0/1000, 
                  rms=0.5, limit=2, seed=i)[0] for i in range(S)])
x = numpy.dot(x_func, basis).T*dv
ensemble = syde556.Ensemble(neurons=N, dimensions=bases, encoders=e)
def my_function(x):
    value = numpy.dot(x, basis.T)
    value = -value
    #value = numpy.hstack([value[100:], value[:100]])
    return numpy.dot(value, basis)*dv
    
    
fx = numpy.array([my_function(xx) for xx in x.T]).T    
decoder = ensemble.compute_decoder(x, fx, noise=0.1)
A, fxhat = ensemble.simulate_rate(x, decoder)
figure(figsize=(10,4))
subplot(1, 2, 1)
plot(v, x_func.T[:,:20])
ylim(-4, 4)
title('original')
subplot(1, 2, 2)
basis = U[:,:bases]/(math.sqrt(dv))
fxhat_func = numpy.dot(basis, fxhat)
plot(v, fxhat_func[:,:20])
title('bases=%d'%bases)
ylim(-4, 4)
show()
    
    
In [ ]: